// Sound.c
// this file takes care of the sound functions.
// basically there are the initialization of the system, and then
// three groups of functions - Sound FX, Audio Clues, and Scene Music.

#define _SOUND_
//#define CHUKWUWETA
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <fcntl.h>
#include <io.h>

#include <time.h>
#include "smack.h"
#include "rad.h"
#include "sound.h"
#include "xenon.h"
#include "player.h"
#include "debug.h"

HDIGDRIVER dig;            // Handle to digital audio driver
extern long g_currentscenenumber;

#define TRUE 1
#define FALSE 0

// initsound -
// Get the whole sound shebang going...

initsound() 
{
	u8 i;
	//
	// Start up AIL 3.0 digital sound system, requesting hardware sample
	// rate as close as possible to 22.050 kHz
	//
	if(!g_gotsound) // player has not confg'd sound in firewall.cfg
		return(FALSE);
	AIL_startup(); // set up AIL drivers, etc

	AIL_set_preference(DIG_HARDWARE_SAMPLE_RATE,22050);
	
	//
	// Initialize digital sound system
	//

	if (AIL_install_DIG_INI(&dig) != AIL_INIT_SUCCESS)
	{
		fatalerror("Run SETUP to select an appropriate digital audio driver");
		AIL_shutdown();
		exit(1);
	}
	// Get Smacker talking to AIL...

	SetSmackAILDigDriver(dig,100);
	//
	// Allocate 15 digital mixer channels, or as many as available
	// this covers all sample handles for music, fx, clues.

	for (i=0; i < N_VOICES; i++)
 	{
		smp[i] = AIL_allocate_sample_handle(dig);
		if (smp[i] == NULL)
		{
			break;
 		}
	}
	num_voices = i;
	return(TRUE);
}

#if 0
long LoadSceneMusic(long scenenumber)
{
long fh;
char musicfile[256],message[100];

#ifdef DEBUGGING_ON
char errbuf[256];
#endif

	if(!g_gotsound)
		return(FALSE);

	if (g_smusicptr != NULL)
	 unLoadSceneMusic();

#ifdef CHUKWUWETA
	sprintf(musicfile,"c:%s",g_music[scenenumber]);
#else
	sprintf(musicfile,"%s%s",g_cdrom,g_music[scenenumber]);
#endif

	g_smusiclen = FILE_size(musicfile);        // AIL function
	if(!(g_smusicptr = FILE_read(musicfile,NULL)))   // AIL function
	 {
	  sprintf(message,"Could not open file %s\n",musicfile);
	  fatalerror(message);
//	  fatalerror("Not enough memory to load background music file\n");
	 }

#ifdef DEBUGGING_ON
sprintf(errbuf, "Total music length = %ld.\n",g_smusiclen);
write_trace(errbuf);
#endif

	if (g_smusicptr == NULL)
		return 0;

	VMM_lock(g_smusicptr, g_smusiclen);   // AIL function
	AIL_init_sample(smp[SMUSIC]);
	AIL_set_sample_type(smp[SMUSIC], DIG_F_MONO_8, 0 );
	AIL_set_sample_address(smp[SMUSIC],g_smusicptr,g_smusiclen);
	AIL_set_sample_playback_rate(smp[SMUSIC],22050);
	AIL_set_sample_volume(smp[SMUSIC],110);
	AIL_set_sample_loop_count(smp[SMUSIC],0); //set for infinite loop - stopped at AIL_end_sample in xenon.c.

   g_soundloadflg |= LOADED_SCENEMUSIC;
   return(TRUE);
}
#endif

long LoadSceneMusic(long scenenumber)
{
long fh;
char musicfile[256],message[100];
struct stat fst;

	if(!g_gotsound)
		return(FALSE);

    GetSceneMusicMemory(-1); //Initialize Scene music memory

#ifdef CHUKWUWETA
	sprintf(musicfile,"c:%s",g_music[scenenumber]);
#else
	sprintf(musicfile,"%s%s",g_cdrom,g_music[scenenumber]);
#endif

    if((fh = open(musicfile, O_RDONLY | O_BINARY)) < 0)
	  return(FALSE);

    fstat(fh,&fst);
	g_smusiclen = fst.st_size;
	g_smusicptr = GetSceneMusicMemory(g_smusiclen);
	read(fh,g_smmemory,g_smusiclen);
	close(fh);

	AIL_init_sample(smp[SMUSIC]);
	AIL_set_sample_type(smp[SMUSIC], DIG_F_MONO_8, 0 );
	AIL_set_sample_address(smp[SMUSIC],g_smusicptr,g_smusiclen);
	AIL_set_sample_playback_rate(smp[SMUSIC],22050);
	AIL_set_sample_volume(smp[SMUSIC],110);
	AIL_set_sample_loop_count(smp[SMUSIC],0); //set for infinite loop - stopped at AIL_end_sample in xenon.c.

   g_soundloadflg |= LOADED_SCENEMUSIC;
   return(TRUE);
}

void unLoadSceneMusic()
{
long fh;
char message[50];

    if(!(g_soundloadflg & LOADED_SCENEMUSIC))
	  return;

   GetSceneMusicMemory(-1); //Reset the scene music

   
   g_soundloadflg &= ~(LOADED_SCENEMUSIC);
}

/*
 * LoadEffects - changed so that we do it by scene.
 *
 * Loads effects - we keep x in memory at all times - gunshots,
 *	tool retrieval, etc.
 */
long LoadEffects(void)
{
    char message[50];
	u8 i,	j, fxstart, fxend;
	char fxfile[128];
	static long lastscenenumber=-1;
	long savet;
	long fh;
	long extramalloced=0,memtotal=0;

	if(!g_gotsound)
		return(FALSE);


#if 0
	if (g_currentscenenumber != lastscenenumber) 
#endif
   if(!(g_soundloadflg & LOADED_EFFECTS))
	{
		lastscenenumber = g_currentscenenumber;
		unLoadEffects();

		switch (g_currentscenenumber)
		{
			case SC_COASTD:
				fxstart = CD_FX_START;
				fxend   = CD_FX_END;
				break;
			case SC_CANYON:
				fxstart = CN_FX_START;
				fxend = CN_FX_END;
				break;
			case SC_GRWALL:
				fxstart = GW_FX_START;
				fxend = GW_FX_END;
				break;
			case SC_PORTAL:
				fxstart = PO_FX_START;
				fxend = PO_FX_END;
				break;
			case SC_INFNET:
				fxstart = IN_FX_START;
				fxend = IN_FX_END;
				break;
			case SC_CITYLT:
				fxstart = CL_FX_START;
				fxend = CL_FX_END;
				break;
			case SC_DATACL:
				fxstart = DC_FX_START;
				fxend = DC_FX_END;
				break;
			case SC_PDEFEN:
				fxstart =PD_FX_START;
				fxend = PD_FX_END;
				break;
			case SC_FIREWL:
				fxstart = FW_FX_START;
				fxend = FW_FX_END;
				break;
			case SC_INWALL:
				fxstart = IW_FX_START;
				fxend = IW_FX_END;
				break;
			case SC_FINALC:
				fxstart = FC_FX_START;
				fxend = FC_FX_END;
				break;
		}

		for (i=fxstart,j=0; i <= fxend; i++,j++)
 		{
	  if(((long) snd[i]  > (long) g_smmemory) && ((long) snd[i] < (long) ((long) g_smmemory + SMMEMORYSIZE)))
	      continue; //Already loaded into g_smmemory;
		            //Pointers all get set to NULL only in unLoadAllSound

#ifdef CHUKWUWETA
			sprintf(fxfile,"c:%s",g_effectname[i]);
#else
			sprintf(fxfile,"%s%s",g_cdrom,g_effectname[i]);
#endif
			siz[j] = FILE_size(fxfile);

            if(g_smmleftover > siz[j])
			 {
              if((fh = open(fxfile, O_RDONLY | O_BINARY)) < 0)
			   continue;

              memtotal+=siz[j];
			  snd[j] = GetSceneMusicMemory(siz[j]);
			  read(fh,snd[j],siz[j]);
			  close(fh);
			  continue; //Dont VMM_Lock it, the whole chunk is 
			            //already locked by the LoadSceneMusic
			 }
			 else if((snd[j] = FILE_read(fxfile,NULL)) == NULL)
			 {
              continue;
			 // sprintf(message,"Error allocating effects sound memory for %s\n",
			 //       fxfile);
			 //  fatalerror(message);
			 }

			if (snd[j] != NULL)
			 {
				VMM_lock(snd[j], siz[j]);   // AIL function
				extramalloced+=siz[j];
				memtotal+=siz[j];
				++g_numeffsmalloced;
		 	 }
	 	}


     g_soundloadflg |= LOADED_EFFECTS;
	}

   return(1);
}

void unLoadEffects()
 {
  short i;
  long  fh;
  char  message[100];
  
    if(!(g_soundloadflg & LOADED_EFFECTS))
	  return;

//Unload the effects
   for (i=11; i>=0; i--)
	{
	  if(((long) snd[i]  > (long) g_smmemory) && ((long) snd[i] < (long) ((long) g_smmemory + SMMEMORYSIZE)))
	     continue;  //Was grabbed from the left over sound memory, cant free

 	  if (snd[i] != NULL)
	   {
		VMM_unlock(snd[i], siz[i]);   // AIL function
		MEM_free(snd[i]);
		snd[i] = NULL;
		--g_numeffsmalloced;
	    }
	}


	g_soundloadflg &= ~(LOADED_EFFECTS);
 }

/*
 * LoadClues
 *
 * Loads clue files by scene.
 */
long LoadClues(void)
{
	u8 i,	j, cluestart, clueend;
	char cluefile[256],errormesg[256];
	static long lastscenenumber=-1;
	int load_it[29];
	FILE *fp;
	long  isthere;
	char  savt;
	long  fh;
	char  message[50];
	long memtotal=0,extramalloced=0;
	long biggestnum,biggestsiz=0;


#ifdef DEBUGGING_ON
long cluesize =0;
char errbuf[256];
#endif

	if(!g_gotsound)
		return(FALSE);


#if 0
	if (g_currentscenenumber != lastscenenumber)
#endif

   if(!(g_soundloadflg & LOADED_CLUES))
	{
		lastscenenumber = g_currentscenenumber;

        unLoadClues();

		for (i=0; i<29; i++)
			load_it[i] = FALSE;

		switch (g_currentscenenumber)
		{
			case SC_COASTD:
				cluestart = CD_CLUE_START;
				clueend = CD_CLUE_END;
				break;
			case SC_CANYON:
				cluestart = CN_CLUE_START;
				clueend = CN_CLUE_END;
				break;
			case SC_GRWALL:
				cluestart = GW_CLUE_START;
				clueend = GW_CLUE_END;
				break;
			case SC_PORTAL:
				cluestart = PO_CLUE_START;
				clueend = PO_CLUE_END;
				break;
			case SC_INFNET:
				cluestart = IN_CLUE_START;
				clueend = IN_CLUE_END;
//				case 0:
					if (g_scenentry[SC_CITYLT] > 0 &&
						!g_weaps[WP_Cyclone].weapaquired &&
				 		 g_playedclue[INCLUE0] == 0)
					{
						load_it[0] = TRUE;
					} 
					// note: clue 1 is never played!
//				case 2:
					if (!g_weaps[WP_HexRipper2].weapaquired)
						load_it[2]=TRUE;
//				case 3:
					if (g_scenentry[SC_DATACL] > 1 && 
						!g_weaps[WP_StunHammer].weapaquired &&
				 		 g_playedclue[INCLUE3] == 0)
					{
						load_it[3] = TRUE;
					}
//				case 4:
					if (g_scenentry[SC_DATACL] > 2 && 
						 g_scenentry[SC_CITYLT] > 1 &&
						!g_weaps[WP_Cyclone].weapaquired &&
				 		 g_playedclue[INCLUE4] == 0)
					{
						load_it[4] = TRUE;
					}
//				case 5:
					if (g_scenentry[SC_DATACL] > 2 && 
						 g_scenentry[SC_CITYLT] > 2 &&
						 g_numtools < 2				 &&
						 g_numweaps < 2				 &&
				 		 g_playedclue[INCLUE5] == 0)
					{
						load_it[5] = TRUE;
					}
//				case 6:
 					if (g_scenentry[SC_INFNET]==1 && 
						 g_playedclue[INCLUE6]==0)
					{
						load_it[6] = TRUE;
					}
//				case 7:
					if (g_scenentry[SC_DATACL] > 2 && 
						 g_scenentry[SC_CITYLT] > 2 && 
				 		 g_playedclue[INCLUE7] == 0)
					{
						load_it[7] = TRUE;
					}
//				case 8:
					if (g_scenentry[SC_DATACL] > 3 && 
				 		 g_playedclue[INCLUE8] == 0)
					{
						load_it[8] = TRUE;
					}
//				case 9:
					if (g_scenentry[SC_CITYLT] >= 2 && 
						!g_weaps[WP_Cyclone].weapaquired &&
				 		 g_playedclue[INCLUE9] == 0)
					{
						load_it[9] = TRUE;
					}
//				case 10:
//					if (g_scenentry[SC_PDEFEN] >= 1 && 
//				 		 g_playedclue[INCLUE10] == 0)
//					{
//						load_it[10] = TRUE;
//					}  //same as case 0, don't load
//				case 11:
					if (g_weaps[WP_Cyclone].weapaquired     &&
						 g_weaps[WP_AIRES].weapaquired       &&
						 g_weaps[WP_CodeSlammer].weapaquired &&
						 g_weaps[WP_StunHammer].weapaquired  &&
				 		 g_playedclue[INCLUE11] == 0)
					{
						load_it[11] = TRUE;
					}
//				case 12:
					if (g_scenentry[SC_DATACL] > 2         &&
						 !g_tools[TL_Passcode2].toolaquired &&
				 		 g_playedclue[INCLUE12] == 0)
					{
						load_it[12] = TRUE;
					}
//				case 13:
					if (g_scenentry[SC_INFNET] > 2         &&
						 !g_tools[TL_Passcode2].toolaquired &&
						 g_tools[TL_Passcode1].toolaquired  &&
				 		 g_playedclue[INCLUE13] == 0)
					{
						load_it[13] = TRUE;
					}
//				case 14:
					if (g_scenentry[SC_INFNET] > 1  &&
						 g_scenentry[SC_CITYLT] <  1 &&
				 		 g_playedclue[INCLUE14] == 0)
					{
						load_it[14] = TRUE;
					}
//				case 15:
					if (g_scenentry[SC_DATACL] > 2            && 
						 !g_weaps[WP_AIRES].weapaquired        &&
						 !g_weaps[WP_CodeSlammer].weapaquired  &&
						 !g_weaps[WP_StunHammer].weapaquired   &&
						 !g_tools[TL_Passcode2].toolaquired    &&
						 !g_tools[TL_TraceCutter1].toolaquired &&
				 		 g_playedclue[INCLUE15] == 0)
					{
						load_it[15] = TRUE;
					}
//				case 16:
 					if (g_scenentry[SC_INFNET]==1         && 
					   !g_tools[TL_Passcode1].toolaquired &&
					   !g_tools[TL_Passcode2].toolaquired &&
						 g_playedclue[INCLUE16]==0)
					{
						load_it[16] = TRUE;
					}
//				case 17:
 					if (g_scenentry[SC_INFNET] > 1 && 
						 !g_weaps[WP_AIRES].weapaquired &&
						 g_playedclue[INCLUE17]==0)
					{
						load_it[17] = TRUE;
					}
//				case 19:
 					if (g_scenentry[SC_DATACL] > 1 && 
						 g_scenentry[SC_CITYLT] > 1 && 
						 g_playedclue[INCLUE19]==0)
					{
						load_it[19] = TRUE;
					}
//				case 20:
 					if (g_scenentry[SC_CITYLT] > 3      && 
						!g_weaps[WP_Cyclone].weapaquired &&
						 g_playedclue[INCLUE20]==0)
					{
						load_it[20] = TRUE;
					}
//				case 21:
 					if (g_scenentry[SC_DATACL] > 3        && 
						 !g_weaps[WP_AIRES].weapaquired    &&
						 !g_weaps[WP_AiresMod].weapaquired &&
						 g_playedclue[INCLUE21]==0)
					{
						load_it[21] = TRUE;
					}
				break;
			case SC_CITYLT:
				cluestart = CL_CLUE_START;
				clueend = CL_CLUE_END;
//				case 0:
					if (g_playedclue[CICLUE0] < 4)
					{
						load_it[0]=TRUE;
					}
//				case 1:
					if (g_playedclue[CICLUE1] == 0)
					{
						load_it[1]=TRUE;
					}
					load_it[2]=TRUE;
//				case 3:
					if (g_playedclue[CICLUE3] < 4)
					{
						load_it[3]=TRUE;
					}
					load_it[4]=TRUE;
//				case 5:
					if (g_playedclue[CICLUE5] < 4)
					{
						load_it[5]=TRUE;
					}
//				case 6:
					if (g_playedclue[CICLUE6] == 0)
					{
						load_it[6]=TRUE;
					}
//				case 7:
					if (g_playedclue[CICLUE7] == 0)
					{
						load_it[7]=TRUE;
					}
//				case 8:
					if (g_playedclue[CICLUE8] == 0 &&
						 g_numweaps < 2)
					{
						load_it[8]=TRUE;
					}
//				case 9:
					if (g_playedclue[CICLUE9] == 0)
					{
						load_it[9]=TRUE;
					}
//				case 10:
					if (g_playedclue[CICLUE10] == 0)
					{
						load_it[10]=TRUE;
					}
//				case 11:
					if (g_playedclue[CICLUE11] == 0)
					{
						load_it[11]=TRUE;
					}
//				case 12:
					if (g_playedclue[CICLUE12] == 0)
					{
						load_it[12]=TRUE;
					}
//				case 13:
					if (g_playedclue[CICLUE13] == 0 &&
 						 g_scenentry[SC_CITYLT] > 1 && 
						 g_switched == FALSE)
					{
						load_it[13]=TRUE;
					}
//				case 14:
					if (g_playedclue[CICLUE14] == 0 &&
						 g_scenentry[SC_CITYLT] > 1) 
					{
						load_it[14]=TRUE;
					}
//				case 15:
					if (g_playedclue[CICLUE15] == 0 &&
						 g_switched == TRUE)
					{
						load_it[15]=TRUE;
					}
//				case 16:
					if (g_playedclue[CICLUE16] == 0 &&
					   !g_tools[TL_Passcode1].toolaquired &&
					   !g_tools[TL_Passcode2].toolaquired)
 					{
						load_it[16]=TRUE;
					}

				break;
			case SC_DATACL:
				cluestart = DC_CLUE_START;
				clueend = DC_CLUE_END;
				load_it[0] = load_it[1] = load_it[2] = load_it[5] = TRUE;
				load_it[6] = load_it[9] = load_it[10] = load_it[11] = TRUE;
				//3,4,7,8,12 no longer exist!
//				case 13: // NOTE! this is how they acquire the aires compiler!
					if (!g_weaps[WP_AiresCom].weapaquired &&  
						 !g_weaps[WP_AIRES].weapaquired)
					{
						load_it[13]=TRUE;
					}
//				case 14:
					if (g_playedclue[DCCLUE14] == 0 &&
						 !g_weaps[WP_StunHammer].weapaquired)
					{
						load_it[14]=TRUE;
					}
//				case 15:
  					if (!g_tools[TL_TraceCutter1].toolaquired &&
  						 !g_tools[TL_TraceCutter2].toolaquired)
					{
						load_it[15]=TRUE;
					}
//				case 16:
					if (g_playedclue[DCCLUE16] < 2 &&
					  !g_tools[TL_Passcode1].toolaquired &&
					  !g_tools[TL_Passcode2].toolaquired)
					{
						load_it[16]=TRUE;
					}
//				case 17:
					if (g_scenentry[SC_DATACL] > 3 && 
				 		 g_playedclue[DCCLUE17] == 0)
					{
						load_it[17]=TRUE;
					}
//				case 18:
					if (g_scenentry[SC_DATACL] > 2 && 
						 g_scenentry[SC_CITYLT] > 2 && 
						 !g_weaps[WP_CodeSlammer].weapaquired  &&
				 		 g_playedclue[DCCLUE18] == 0)
					{
						load_it[18]=TRUE;
					}
//				case 19:
					if (g_scenentry[SC_DATACL] > 2 && 
						 g_scenentry[SC_CITYLT] > 2 && 
						 g_numweaps < 3 &&
				 		 g_playedclue[DCCLUE19] == 0)
					{
						load_it[19]=TRUE;
					}
//				case 20:
					if (!g_weaps[WP_CodeSlammer].weapaquired &&
				 		 g_playedclue[DCCLUE20] == 0)
					{
						load_it[20]=TRUE;
					}
				break;

			case SC_PDEFEN:
				cluestart =PD_CLUE_START;
				clueend   =PD_CLUE_END;
				for (i=0; i<13; i++)
					load_it[i]=TRUE;
#if 0
					load_it[13]=TRUE;
					load_it[14]=TRUE;
				    load_it[15]=TRUE;
				    load_it[16]=TRUE;
					load_it[17]=TRUE;
				    load_it[19]=TRUE;
				    load_it[21]=TRUE;
					load_it[22]=TRUE;
					load_it[23]=TRUE;
			        load_it[24]=TRUE;
				    load_it[25]=TRUE;
				    load_it[26]=TRUE;
#endif

#if 1
					if (g_playedclue[PDCLUE13] == 0) load_it[13]=TRUE;
					if (g_playedclue[PDCLUE14] == 0) load_it[14]=TRUE;
					if (g_playedclue[PDCLUE15] == 0 &&
						 g_scenentry[SC_PDEFEN] > 1) load_it[15]=TRUE;
					if (g_playedclue[PDCLUE16] == 0) load_it[16]=TRUE;
					if (g_playedclue[PDCLUE17] == 0 &&
						 g_weaps[WP_Cyclone].weapaquired     &&
						 g_weaps[WP_AiresCom].weapaquired    &&
						!g_weaps[WP_AiresMod].weapaquired    &&
						 g_weaps[WP_CodeSlammer].weapaquired &&
						 g_weaps[WP_StunHammer].weapaquired)
						load_it[17]=TRUE;

					if (g_playedclue[PDCLUE19] == 0 	     &&
						 g_weaps[WP_Cyclone].weapaquired     &&
						 g_weaps[WP_AIRES].weapaquired 		 &&
						 g_weaps[WP_CodeSlammer].weapaquired &&
						 g_weaps[WP_StunHammer].weapaquired)
					{
						load_it[19]=TRUE;
					}
					if (g_playedclue[PDCLUE21] == 0)  load_it[21]=TRUE;
					if (g_playedclue[PDCLUE22] == 0)  load_it[22]=TRUE;
					if (g_playedclue[PDCLUE23] == 0)  load_it[23]=TRUE;
					if (g_playedclue[PDCLUE24] == 0 && 
						 g_scenentry[SC_PDEFEN] > 1)  load_it[24]=TRUE;
					if (g_playedclue[PDCLUE25] == 0 && 
					  !g_tools[TL_LabKey].toolaquired &&
						 g_scenentry[SC_PDEFEN] > 1) load_it[25]=TRUE;
					if (g_playedclue[PDCLUE26] < 2)  load_it[26]=TRUE;
#endif
				break;

			case SC_FIREWL:
				cluestart = FW_CLUE_START;
				clueend = FW_CLUE_END;
				break;
			case SC_INWALL:
				cluestart = IW_CLUE_START;
				clueend = IW_CLUE_END;
				break;
			case SC_FINALC:
				cluestart = FC_CLUE_START;
				clueend = FC_CLUE_END;
				break;
		}
		if ((g_currentscenenumber == SC_INFNET) ||
			 (g_currentscenenumber == SC_CITYLT) ||
			 (g_currentscenenumber == SC_DATACL) ||
			 (g_currentscenenumber == SC_PDEFEN))
		{

			for (i=cluestart,j=0; i <= clueend; i++,j++)
 			{
	           if(((long) clueptr[i]  > (long) g_smmemory) && 
			      ((long) clueptr[i] < (long) ((long) g_smmemory + SMMEMORYSIZE)))
				   continue;

				if (load_it[j] == TRUE)
				{
#ifdef CHUKWUWETA
				sprintf(cluefile,"c:%s",g_clue[i]);
#else
				sprintf(cluefile,"%s%s",g_cdrom,g_clue[i]);
#endif
			  if(!(cluelen[j] = FILE_size(cluefile)))
			   continue; //File not there

              if(g_smmleftover > cluelen[j])
			  {
                if((fh = open(cluefile, O_RDONLY | O_BINARY)) < 0)
			     continue;

              memtotal+=cluelen[j];
			  clueptr[j] = GetSceneMusicMemory(cluelen[j]);
			  read(fh,clueptr[j],cluelen[j]);
			  close(fh);




			  continue; //Dont VMM_Lock it, the whole chunk is 
			            //already locked by the LoadSceneMusic
			 }
             else
			  {
				clueptr[j] = FILE_read(cluefile,NULL);
				if (clueptr[j] != NULL)
				   {
						VMM_lock(clueptr[j], cluelen[j]);   // AIL function
						++g_numcluesmalloced;
						if(cluelen[j] > biggestsiz)
						 {
						  biggestsiz=cluelen[j];
						  biggestnum=j;
						 }

						memtotal+=cluelen[j];
					    extramalloced+=cluelen[j];
                   }
			   }
			}
		  }
		}
		else
		{
			for (i=cluestart,j=0; i <= clueend; i++,j++)
 			{
	           if(((long) clueptr[i]  > (long) g_smmemory) && 
			      ((long) clueptr[i] < (long) ((long) g_smmemory + SMMEMORYSIZE)))
				  continue;

#ifdef CHUKWUWETA
				sprintf(cluefile,"c:%s",g_clue[i]);
#else
				sprintf(cluefile,"%s%s",g_cdrom,g_clue[i]);
#endif

		    if(!(cluelen[j] = FILE_size(cluefile)))
			 continue;
            
              if(g_smmleftover > cluelen[j])
			  {
               if((fh = open(cluefile, O_RDONLY | O_BINARY)) < 0)
			     continue;

              memtotal+=cluelen[j];
			  clueptr[j] = GetSceneMusicMemory(cluelen[j]);
			  read(fh,clueptr[j],cluelen[j]);
			  close(fh);

			  continue; //Dont VMM_Lock it, the whole chunk is 
			            //already locked by the LoadSceneMusic
			 } else
			  {
				if((clueptr[j] = FILE_read(cluefile,NULL)) == NULL)
				   fatalerror("Error allocating clue sound memory\n");

				if (clueptr[j] != NULL)
				 {
					VMM_lock(clueptr[j], cluelen[j]);   // AIL function
						++g_numcluesmalloced;
						if(cluelen[j] > biggestsiz)
						 {
						  biggestsiz=cluelen[j];
						  biggestnum=j;
						 }

                    memtotal+=cluelen[j];
					extramalloced+=cluelen[j];
				}
			  }
		 	}
		}

 	 g_soundloadflg |= LOADED_CLUES;
	}

    sprintf(message,"The biggest clue malloced was %d with size %d\n",
	        biggestnum,biggestsiz);
//    fatalerror(message);

	return(1);
}

void unLoadClues()
{
 short i;
 long  fh;
 char  message[50];

  if(!(g_soundloadflg & LOADED_CLUES))
    return;

 //Unload the clues
    for (i=31; i>=0; i--) 
 	 {
	  if(clueptr[i] == NULL)
	    continue;

         if(((long) clueptr[i]  > (long) g_smmemory) && 
	        ((long) clueptr[i] < (long) ((long) g_smmemory + SMMEMORYSIZE)))
			  continue; //Placed in g_smmemory, can't free

	  if (clueptr[i] != NULL)
 	   {
		VMM_unlock(clueptr[i], cluelen[i]);   // AIL function
	 	MEM_free(clueptr[i]);
	 	clueptr[i] = NULL;
		--g_numcluesmalloced;
	   }
	}


	g_soundloadflg &= ~(LOADED_CLUES);
}

void unLoadBiggestClue()
 {

 }

// playSoundFX - initialize sample and start sound fx playing
long playSoundFX(long effect)
{

	if(!g_gotsound)
		return(FALSE);

    if(!smp[effect]) 
	 return(FALSE);

	AIL_init_sample(smp[effect]);
	AIL_set_sample_type(smp[effect], DIG_F_MONO_8, 0 );
	AIL_set_sample_address(smp[effect],snd[effect],siz[effect]);
	AIL_set_sample_playback_rate(smp[effect],22050);
	AIL_set_sample_volume(smp[effect],100);
	AIL_set_sample_loop_count(smp[effect],1); // set for 1 iteration - testing! 
													//  Strange hiccups at scene change!
	AIL_start_sample(smp[effect]);
	return(TRUE);
}


// playClue - initalize and start a clue playing
long playClue(long cluetoplay)
{
	if(!g_gotsound)
		return(FALSE);

	AIL_init_sample(smp[CLUE]);
	AIL_set_sample_type(smp[CLUE], DIG_F_MONO_8, 0 );
	AIL_set_sample_address(smp[CLUE],clueptr[cluetoplay],cluelen[cluetoplay]);
	AIL_set_sample_playback_rate(smp[CLUE],22050);
	AIL_set_sample_volume(smp[CLUE],110);
	AIL_start_sample(smp[CLUE]);
	if (cluetoplay != REPLAY)
	{
		clueptr[REPLAY] = clueptr[cluetoplay];
		cluelen[REPLAY] = cluelen[cluetoplay];
	}

	return(TRUE);
}

// a special case for playing the miracom engineer clues - they are
// very large and I'm loading and playing them here to save space!

long playMEClue(int x)
{
	char cluefile[256];

	if(!g_gotsound)
		return(FALSE);
	switch (x)
	{
		case 17:
			sprintf(cluefile,"%s\\data\\sound\\me71.wav",g_cdrom);
			break;
		case 18:
			sprintf(cluefile,"%s\\data\\sound\\me72.wav",g_cdrom);
			break;
		case 19:
			sprintf(cluefile,"%s\\data\\sound\\me73.wav",g_cdrom);
			break;
		case 20:
			sprintf(cluefile,"%s\\data\\sound\\me74.wav",g_cdrom);
			break;
		case 21:
			sprintf(cluefile,"%s\\data\\sound\\me75.wav",g_cdrom);
			break;
		case 22:
			sprintf(cluefile,"%s\\data\\sound\\me76.wav",g_cdrom);
			break;
		default:
			return(FALSE);
	}

	if (clueptr[17] != NULL)
	{
		VMM_unlock(clueptr[17], cluelen[17]);   // AIL function
		MEM_free(clueptr[17]);
		clueptr[17] = NULL;
	}
	cluelen[17] = FILE_size(cluefile);
	clueptr[17] = FILE_read(cluefile,NULL);
	if (clueptr[17] != NULL)
		VMM_lock(clueptr[17], cluelen[17]);   // AIL function

	AIL_init_sample(smp[CLUE]);
	AIL_set_sample_type(smp[CLUE], DIG_F_MONO_8, 0 );
	AIL_set_sample_address(smp[CLUE],clueptr[17],cluelen[17]);
	AIL_set_sample_playback_rate(smp[CLUE],22050);
	AIL_set_sample_volume(smp[CLUE],110);
	AIL_start_sample(smp[CLUE]);
	if (x != REPLAY)
	{
		clueptr[REPLAY] = clueptr[17];
		cluelen[REPLAY] = cluelen[17];
	}
	return(TRUE);
}

// playSceneMusic - take one of the sample handles and point it at
//		the specified (x) .wav file.  Start the music playing...


long playSceneMusic(void)
{
	if(!g_gotsound)
		return(FALSE);
	AIL_start_sample(smp[SMUSIC]);  // start it up...
	return(TRUE);
}

void changeVolume(long vol)
{
	static FILE *fp;

	if(!g_gotsound)
		return;
	g_soundvol = vol;
	AIL_set_digital_master_volume(dig,vol);
	fp=fopen("c:firewall.cfg","r+b");
   fseek(fp,16,SEEK_SET);
   fwrite(&g_soundvol,sizeof(long),1,fp);
   fclose(fp);
}

/*-----------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
void processSpecialClue(long clue)
{
	static short fwall_loop_ctr=0;

	if (AIL_sample_status(smp[CLUE]) != SMP_DONE)
		return;
	switch(g_currentscenenumber)
	{
		case SC_COASTD:
			break;
		case SC_CANYON:
			switch (clue)
			{
				case 3:
					if (g_playedclue[CACLUE3] == 0)
					{
						playClue(CACLUE3);
						g_playedclue[CACLUE3]++;
					}
					break;
				case 4:
					if (g_playedclue[CACLUE4] == 0  &&
						 g_playedclue[CACLUE3] > 0)
					{
						playClue(CACLUE4);
						g_playedclue[CACLUE4]++;
					}
					break;
				default:
					break;
				}
			break;
		case SC_GRWALL:
			break;
		case SC_PORTAL:
			switch (clue)
			{
				case 2:
					playClue(clue);
					break;
				default:
					break;
			}
			break;
		case SC_INFNET:
			switch (clue) 
			{
				// NOTE these 3 (0, 3 & 4) clues are tied to the blue 'clue'
				//  packet!  If the player doesn't satisfy one condition, drop  
				//  through to see if they satisfy another!  They 
				//  are all tied to clue 0 because I can only use one in the
				//  the event file -MCR
				case 0:
//				case 3:
					if (g_scenentry[SC_DATACL] > 1 && 
						!g_weaps[WP_StunHammer].weapaquired &&
				 		 g_playedclue[INCLUE3] == 0)
					{
						playClue(3);
						g_playedclue[INCLUE3]++;
						break;
					}
//				case 0:
					if (g_scenentry[SC_CITYLT] > 0 &&
						!g_weaps[WP_Cyclone].weapaquired &&
				 		 g_playedclue[INCLUE0] == 0)
					{
						playClue(0);
						g_playedclue[INCLUE0]++;
						break;
					}
//				case 4:
					if (g_scenentry[SC_DATACL] > 2 && 
						 g_scenentry[SC_CITYLT] > 1 &&
						!g_weaps[WP_Cyclone].weapaquired &&
				 		 g_playedclue[INCLUE4] == 0)
					{
						playClue(4);
						g_playedclue[INCLUE4]++;
						break;
					}
					strcpy(g_blinktxt.blinktext, "EMPTY PACKET\n");
					g_blinktxt.numframes = NUMBLINKFRAMES;
					break;
				// That's the end of the 'clue packet' clues for Infonet.
					
				case 5:
					if (g_scenentry[SC_DATACL] > 2 && 
						 g_scenentry[SC_CITYLT] > 2 &&
						 g_numtools < 2				 &&
						 g_numweaps < 2				 &&
				 		 g_playedclue[INCLUE5] == 0)
					{
						playClue(clue);
						g_playedclue[INCLUE5]++;
					}
					break;
				case 6:
 					if (g_scenentry[SC_INFNET]==1 && 
						 g_playedclue[INCLUE6]==0)
					{
						playClue(clue);
						g_playedclue[INCLUE6]++;
					}
					break;
				case 7:
					if (g_scenentry[SC_DATACL] > 2 && 
						 g_scenentry[SC_CITYLT] > 2 && 
				 		 g_playedclue[INCLUE7] == 0)
					{
						playClue(clue);
						g_playedclue[INCLUE7]++;
					}
					break;
				case 8:
					if (g_scenentry[SC_DATACL] > 3 && 
				 		 g_playedclue[INCLUE8] == 0)
					{
						playClue(clue);
						g_playedclue[INCLUE8]++;
					}
					break;
				case 9:
					if (g_scenentry[SC_CITYLT] >= 2 && 
						!g_weaps[WP_Cyclone].weapaquired &&
				 		 g_playedclue[INCLUE9] == 0)
					{
						playClue(clue);
						g_playedclue[INCLUE9]++;
					}
					break;
				case 10:
					if (g_scenentry[SC_PDEFEN] >= 1 && 
				 		 g_playedclue[INCLUE10] == 0)
					{
						playClue(clue);
						g_playedclue[INCLUE10]++;
					}
					break;
				case 11:
					if (g_weaps[WP_Cyclone].weapaquired     &&
						 g_weaps[WP_AIRES].weapaquired       &&
						 g_weaps[WP_CodeSlammer].weapaquired &&
						 g_weaps[WP_StunHammer].weapaquired  &&
				 		 g_playedclue[INCLUE11] == 0)
					{
						playClue(clue);
						g_playedclue[INCLUE11]++;
					}
					break;
				case 12:
					if (g_scenentry[SC_DATACL] > 2     &&
						 !g_tools[TL_Passcode2].toolaquired &&
				 		 g_playedclue[INCLUE12] == 0)
					{
						playClue(clue);
						g_playedclue[INCLUE12]++;
					}
					break;
				case 13:
					if (g_scenentry[SC_INFNET] > 2     &&
						 !g_tools[TL_Passcode2].toolaquired &&
						 g_tools[TL_Passcode1].toolaquired &&
				 		 g_playedclue[INCLUE13] == 0)
					{
						playClue(clue);
						g_playedclue[INCLUE13]++;
					}
					break;
				case 14:
					if (g_scenentry[SC_INFNET] > 1  &&
						 g_scenentry[SC_CITYLT] <  1 &&
				 		 g_playedclue[INCLUE14] == 0)
					{
						playClue(clue);
						g_playedclue[INCLUE14]++;
					}
					break;				
				case 15:
					if (g_scenentry[SC_DATACL] > 2 && 
						 !g_weaps[WP_AIRES].weapaquired       &&
						 !g_weaps[WP_CodeSlammer].weapaquired &&
						 !g_weaps[WP_StunHammer].weapaquired  &&
						 !g_tools[TL_Passcode2].toolaquired   &&
						 !g_tools[TL_TraceCutter1].toolaquired &&
				 		 g_playedclue[INCLUE15] == 0)
					{
						playClue(clue);
						g_playedclue[INCLUE15]++;
					}
					break;
				case 16:
 					if (g_scenentry[SC_INFNET]==1 && 
					   !g_tools[TL_Passcode1].toolaquired &&
					   !g_tools[TL_Passcode2].toolaquired &&
						 g_playedclue[INCLUE16]==0)
					{
						playClue(clue);
						g_playedclue[INCLUE16]++;
					}
					break;
				case 17:
 					if (g_scenentry[SC_INFNET] > 1 && 
						 !g_weaps[WP_AIRES].weapaquired &&
						 g_playedclue[INCLUE17]==0)
					{
						playClue(clue);
						g_playedclue[INCLUE17]++;
					}
					break;
				case 19:
 					if (g_scenentry[SC_DATACL] > 1 && 
						 g_scenentry[SC_CITYLT] > 1 && 
						 g_playedclue[INCLUE19]==0)
					{
						playClue(clue);
						g_playedclue[INCLUE19]++;
					}
					break;
				case 20:
 					if (g_scenentry[SC_CITYLT] > 3 && 
						!g_weaps[WP_Cyclone].weapaquired &&
						 g_playedclue[INCLUE20]==0)
					{
						playClue(clue);
						g_playedclue[INCLUE20]++;
					}
					break;
				case 21:
 					if (g_scenentry[SC_DATACL] > 3 && 
						 !g_weaps[WP_AIRES].weapaquired &&
						 !g_weaps[WP_AiresMod].weapaquired &&
						 g_playedclue[INCLUE21]==0)
					{
						playClue(clue);
						g_playedclue[INCLUE21]++;
					}
					break;
				default:
					break;
			}
			break;
		case SC_CITYLT:  //NOTE!! this includes the "ME" clues - the memorandum
							// accessed at the 'database' in COL!
			switch (clue) 
			{
				case 0:
					if (g_playedclue[CICLUE0] < 4)
					{
						playClue(clue);
						g_playedclue[CICLUE0]++;
					}
					break;
				case 1:
					if (g_playedclue[CICLUE1] == 0)
					{
						playClue(clue);
						g_playedclue[CICLUE1]++;
					}
					break;
				case 3:
					if (g_playedclue[CICLUE3] < 4)
					{
						playClue(clue);
						g_playedclue[CICLUE3]++;
					}
					break;
				case 5:
					if (g_playedclue[CICLUE5] < 4)
					{
						playClue(clue);
						g_playedclue[CICLUE5]++;
					}
					break;
				case 6:
					if (g_playedclue[CICLUE6] == 0)
					{
						playClue(clue);
						g_playedclue[CICLUE6]++;
					}
					break;
				case 7:
					if (g_playedclue[CICLUE7] == 0)
					{
						playClue(clue);
						g_playedclue[CICLUE7]++;
					}
					break;
				case 8:
					if (g_playedclue[CICLUE8] == 0 &&
						 g_numweaps < 2)
					{
						playClue(clue);
						g_playedclue[CICLUE8]++;
					}
					break;
				case 9:
					if (g_playedclue[CICLUE9] == 0)
					{
						playClue(clue);
						g_playedclue[CICLUE9]++;
					}
					break;
				case 10:
					if (g_playedclue[CICLUE10] == 0)
					{
						playClue(clue);
						g_playedclue[CICLUE10]++;
					}
					break;
				case 11:
					if (g_playedclue[CICLUE11] == 0)
					{
						playClue(clue);
						g_playedclue[CICLUE11]++;
					}
					break;
				case 12:
					if (g_playedclue[CICLUE12] == 0)
					{
						playClue(clue);
						g_playedclue[CICLUE12]++;
					}
					break;
				case 13:
					if (g_playedclue[CICLUE13] == 0 &&
 						 g_scenentry[SC_CITYLT] > 1 && 
						 g_switched == FALSE)
					{
						playClue(clue);
						g_playedclue[CICLUE13]++;
					}
					break;
				case 14:
					if (g_playedclue[CICLUE14] == 0 &&
						 g_scenentry[SC_CITYLT] > 1) 
					{
						playClue(clue);
						g_playedclue[CICLUE14]++;
					}
					break;
				case 15:
					if (g_playedclue[CICLUE15] == 0 &&
						 g_switched == TRUE)
					{
						playClue(clue);
						g_playedclue[CICLUE15]++;
					}
					break;
				case 16:
					if (g_playedclue[CICLUE16] == 0 &&
					   !g_tools[TL_Passcode1].toolaquired &&
					   !g_tools[TL_Passcode2].toolaquired)
 					{
						playClue(clue);
						g_playedclue[CICLUE16]++;
					}
					break;
			// Memorandums were added at the end in a hurry - they are not in 
			// proper order in sound.h - Mary, fix this if/when you have time.

				case 17:	// this includes clues 17 - 22 (the memorandum!)
							// these are accessed sequentially from 17 down!
							//NOTE! because these clues are very large I am
							// loading and playing them separately!!
					if (g_playedclue[MECLUE0] == 0)
					{
						playMEClue(17);
						g_playedclue[MECLUE0]++;
						break;
					}
//				case 18:
					if (g_playedclue[MECLUE1] == 0)
					{
						playMEClue(18);
						g_playedclue[MECLUE1]++;
						break;
					}
//				case 19:
					if (g_playedclue[MECLUE2] == 0)
					{
						playMEClue(19);
						g_playedclue[MECLUE2]++;
						break;
					}
//				case 20:
					if (g_playedclue[MECLUE3] == 0)
					{
						playMEClue(20);
						g_playedclue[MECLUE3]++;
						break;
					}
//				case 21:
					if (g_playedclue[MECLUE4] == 0)
					{
						playMEClue(21);
						g_playedclue[MECLUE4]++;
						break;
					}
//				case 22:
					if (g_playedclue[MECLUE5] == 0)
					{
						playClue(22);
						g_playedclue[MECLUE5]++;
						break;
					}
					break;
				default:
					break;
			}
			break;
		case SC_DATACL:
			switch (clue)
			{ // note cases 20 and 13 are together because they are both stored
			  // in a blue data packet.  The clue is set to 12 (I can only set one
			  // in the event file), but will drop thru to 13 if it's already been
			  // played. -MCR
				case 20:
					if (!g_weaps[WP_CodeSlammer].weapaquired &&
				 		 g_playedclue[DCCLUE20] == 0)
					{
						playClue(20);
						g_playedclue[DCCLUE20]++;
						break;
					}
//				case 13: // NOTE! this is how they acquire the aires compiler!
					if (!g_weaps[WP_AiresCom].weapaquired &&  
							!g_weaps[WP_AIRES].weapaquired)
					{
						playClue(13);
						g_playedclue[DCCLUE13]++; 
						g_numweaps++;  // increment total number of acquired weapons (for clue purposes)
						sprintf(g_blinktxt.blinktext, "AIRES COMPILER AQUIRED");
						g_blinktxt.numframes = NUMBLINKFRAMES;
						g_weaps[WP_AiresCom].weapaquired = TRUE;
						if((g_weaps[WP_AiresCom].weapaquired == TRUE) &&
							(g_weaps[WP_AiresMod].weapaquired == TRUE))
						{
							strcpy(g_blinktxt.blinktext, " AIRES FULLY ACTIVATED\n");
							g_weaps[WP_AiresCom].weapaquired = FALSE;
							g_weaps[WP_AiresMod].weapaquired = FALSE;
							g_weaps[WP_AIRES].weapaquired = TRUE;
							if((g_selectedweap == WP_AiresCom) ||
								(g_selectedweap == WP_AiresMod))
								g_selectedweap = WP_AIRES;
						}
						break;
					}
					strcpy(g_blinktxt.blinktext, "EMPTY PACKET\n");
					g_blinktxt.numframes = NUMBLINKFRAMES;
					break;
				case 14:
					if (g_playedclue[DCCLUE14] == 0)
					{
						playClue(clue);
						g_playedclue[DCCLUE14]++;
					}
					break;
			case 15:
  					if (!g_tools[TL_TraceCutter1].toolaquired &&
  						 !g_tools[TL_TraceCutter2].toolaquired)
					{
						playClue(clue);
						g_playedclue[DCCLUE15]++;
					}
					break;
				case 16:
					if (g_playedclue[DCCLUE16] < 2 &&
					  !g_tools[TL_Passcode1].toolaquired &&
					  !g_tools[TL_Passcode2].toolaquired)
					{
						playClue(clue);
						g_playedclue[DCCLUE16]++;
					}
					break;
				case 17:
					if (g_scenentry[SC_DATACL] > 3 && 
				 		 g_playedclue[DCCLUE17] == 0)
					{
						playClue(clue);
						g_playedclue[DCCLUE17]++;
					}
					break;
				case 18:
					if (g_scenentry[SC_DATACL] > 2 && 
						 g_scenentry[SC_CITYLT] > 2 && 
				 		 g_playedclue[DCCLUE18] == 0)
					{
						playClue(clue);
						g_playedclue[DCCLUE18]++;
					}
					break;
				case 19:
					if (g_scenentry[SC_DATACL] > 2 && 
						 g_scenentry[SC_CITYLT] > 2 && 
						 g_numweaps < 4 &&
				 		 g_playedclue[DCCLUE19] == 0)
					{
						playClue(clue);
						g_playedclue[DCCLUE19]++;
					}
					break;
				default:
					break;
			}
			break;
		case SC_PDEFEN:
			switch (clue)
			{
				case 13:
					if (g_playedclue[PDCLUE13] == 0)
					{
						playClue(clue);
						g_playedclue[PDCLUE13]++;
					}
					break;
				case 14:
					if (g_playedclue[PDCLUE14] == 0)
					{
						playClue(clue);
						g_playedclue[PDCLUE14]++;
					}
					break;
				case 15:
					if (g_playedclue[PDCLUE15] == 0 &&
						 g_scenentry[SC_DATACL] > 2)
					{
						playClue(clue);
						g_playedclue[PDCLUE15]++;
					}
					break;
				case 16:
					if (g_playedclue[PDCLUE16] == 0)
					{
						playClue(clue);
						g_playedclue[PDCLUE16]++;
					}
					break;
				case 17:
					if (g_playedclue[PDCLUE17] == 0 &&
						 g_weaps[WP_Cyclone].weapaquired     &&
						 g_weaps[WP_AiresCom].weapaquired    &&
						!g_weaps[WP_AiresMod].weapaquired    &&
						 g_weaps[WP_CodeSlammer].weapaquired &&
						 g_weaps[WP_StunHammer].weapaquired)
					{
						playClue(clue);
						g_playedclue[PDCLUE17]++;
					}
					break;
				case 19:
					if (g_playedclue[PDCLUE19] == 0 &&
						 g_weaps[WP_Cyclone].weapaquired     &&
						 g_weaps[WP_AIRES].weapaquired 		 &&
						 g_weaps[WP_CodeSlammer].weapaquired &&
						 g_weaps[WP_StunHammer].weapaquired)
					{
						playClue(clue);
						g_playedclue[PDCLUE19]++;
					}
					break;
				case 20:
					if (g_playedclue[PDCLUE20] == 0) 
					{
						playClue(clue);
						g_playedclue[PDCLUE20]++;
					}
					break;
				case 21:
					if (g_playedclue[PDCLUE21] == 0) 
					{
						playClue(clue);
						g_playedclue[PDCLUE22]++;
					}
					break;
				case 22:
					if (g_playedclue[PDCLUE22] == 0) 
					{
						playClue(clue);
						g_playedclue[PDCLUE22]++;
					}
					break;
				case 23:
					if (g_playedclue[PDCLUE23] == 0) 
					{
						playClue(clue);
						g_playedclue[PDCLUE23]++;
					}
					break;
				case 24:
					if (g_playedclue[PDCLUE24] == 0 && 
						 g_scenentry[SC_DATACL] > 1)
					{
						playClue(clue);
						g_playedclue[PDCLUE24]++;
					}
					break;
				case 25:
					if (g_playedclue[PDCLUE25] == 0 && 
					  !g_tools[TL_LabKey].toolaquired &&
						 g_scenentry[SC_DATACL] > 1)
					{
						playClue(clue);
						g_playedclue[PDCLUE25]++;
					}
					break;
				case 26:
					if (g_playedclue[PDCLUE26] < 2)
					{
						playClue(clue);
						g_playedclue[PDCLUE26]++;
					}
					break;
				default:
					break;
			}
			break;
		case SC_FIREWL:
			switch (clue) 
			{
				case 7:
					if (g_playedclue[FWCLUE7]==0)
					{
						playClue(clue);
						g_playedclue[FWCLUE7]++;
					}
					break;
				case 8:
					if (++fwall_loop_ctr > 2 &&
						 g_playedclue[FWCLUE8]==0)
					{
						playClue(clue);
						g_playedclue[FWCLUE8]++;
					}
					break;
				case 9:
					if (g_playedclue[FWCLUE9]==0)
					{
						playClue(clue);
						g_playedclue[FWCLUE9]++;
					}
					break;
				case 10:
					if (g_playedclue[FWCLUE10]<4)
					{
						playClue(clue);
						g_playedclue[FWCLUE10]++;
					}
					break;
				default:
					break;
			}
			break;
		case SC_INWALL:
			switch (clue) 
			{
				case 1:
					if (g_scenentry[SC_INWALL] > 1 &&
						g_selectedtool != TL_TraceCutter2)
					{
						playClue(clue);
						g_playedclue[IWCLUE1]++;
					}
					break;
				case 3:
					if (g_playedclue[IWCLUE3] == 0)
					{
						playClue(clue);
						g_playedclue[IWCLUE3]++;
					}
					break;
				case 4:
					if (g_playedclue[IWCLUE4] == 0)
					{
						playClue(clue);
						g_playedclue[IWCLUE4]++;
					}
					break;
				case 5:
					if (g_playedclue[IWCLUE5] == 0)
					{
						playClue(clue);
						g_playedclue[IWCLUE5]++;
					}
					break;
				case 6:
					if (g_playedclue[IWCLUE6] == 0)
					{
						playClue(clue);
						g_playedclue[IWCLUE6]++;
					}
					break;
				default:
					break;
			}
			break;
		case SC_FINALC:
			switch (clue) 
			{
				case 10:
					if (g_playedclue[FCCLUE10] < 3)
					{
						playClue(clue);
						g_playedclue[FCCLUE10]++;
					}
					break;
				default:
					break;
			}
			break;
		default:
			break;
	}
}

void unLoadAllSound()
 {
  long i;
  long freepnt = 0;
  short isclue=-1,iseffect=-1,isscenemusic=-1;

 clueptr[REPLAY] = NULL;
 cluelen[REPLAY] = 0;

 while(g_numcluesmalloced || g_numeffsmalloced)
 {
  freepnt=0;

  if(g_numeffsmalloced)
   for(i = 0; i < NUMEFFECT; ++i)
    {
	  if(!snd[i])  continue;

	  if(((long) snd[i]  > (long) g_smmemory) && ((long) snd[i] < ((long) g_smmemory + SMMEMORYSIZE)))
	   {
	    snd[i] = NULL;
		siz[i] = 0;
	    continue;  //Was grabbed from the left over sound memory, cant free
	   }

	  if(!freepnt)
	   {
         freepnt = (long) snd[i];
		 iseffect=i;
		 isclue=isscenemusic=-1;
	   }
	   else if(snd[i])
	   {
	    if(freepnt < (long) snd[i])
		 {
		   iseffect=i;
		   isclue=isscenemusic=-1;
		   freepnt = (long) snd[i];
		 }
	   }
	}

  if(g_numcluesmalloced)
   for(i = 0; i < 32; ++i)
    {
	  if(!clueptr[i]) continue;
	  if(((long) clueptr[i]  > (long) g_smmemory) && 
	     ((long) clueptr[i] < ((long) g_smmemory + SMMEMORYSIZE)))
	   {
	    clueptr[i] = NULL;
		cluelen[i] = 0;
	    continue;  //Was grabbed from the left over sound memory, cant free
	   }

	  if(!freepnt)
	   {
         freepnt = (long) clueptr[i];
		 iseffect=isscenemusic=-1;
		 isclue=i;
	   }
	   else
	   {
	    if(freepnt < (long) clueptr[i])
		 {
		   iseffect=isscenemusic=-1;
		   isclue=i;
		   freepnt = (long) clueptr[i];
		 }
	   }
	}

	if(iseffect >  -1)
	 {
	  VMM_unlock(snd[iseffect], siz[iseffect]);   // AIL function
	  free((void *) freepnt);
	  snd[iseffect] = NULL;
	  siz[iseffect] = 0;
	  --g_numeffsmalloced;
	  iseffect = isclue = isscenemusic=-1;
	  continue;
	 }

	if(isclue >  -1)
	 {
	  VMM_unlock(clueptr[isclue], cluelen[isclue]);   // AIL function
	  free((void *) freepnt);
	  clueptr[isclue] = NULL;
	  cluelen[isclue] = 0;
	  --g_numcluesmalloced;
	  iseffect = isclue = isscenemusic=-1;
	  continue;
	 }

    if(1)
     break; //Failsafe If we got here, it must not have found anything
  }

  unLoadSceneMusic();
  g_soundloadflg=0;

  memset(siz,0,(NUMEFFECT * sizeof(long)));
  memset(snd,0,(NUMEFFECT * sizeof(void *)));
  memset(clueptr,0,(32 * sizeof(void *)));
  memset(cluelen,0,(32 * sizeof(long)));

#if 0
  unLoadEffects();
  unLoadClues();
  unLoadSceneMusic();
#endif
 }

#if 0
void LoadAllSound()
 {
  //  LoadSceneMusic(g_currentscenenumber);
    LoadClues();
    LoadEffects();
 }
#endif

long unLoadSomeSound()
 {
  long i;

 if(g_soundloadflg & LOADED_EFFECTS)
  {unLoadEffects(); return(1);}

 if(g_soundloadflg & LOADED_CLUES)
  {unLoadClues(); return(1);}

// if(g_soundloadflg & LOADED_SCENEMUSIC)
//  {unLoadSceneMusic(); return(1);}

   return(0);
 }

void LoadSomeSound()
 {
   if(!(g_soundloadflg & LOADED_SCENEMUSIC))
    LoadSceneMusic(g_currentscenenumber);

   if(!(g_soundloadflg & LOADED_CLUES))
    LoadClues();

   if(!(g_soundloadflg & LOADED_EFFECTS))
    LoadEffects();
 }


void *GetSceneMusicMemory(long amtreq)
{
 static void *freemempntr,*retmempntr;
 char *errormsg1 = "Not enough memory for Firewall scene music data files\n";
 char *errormsg2 = "Availible Firewall scene music memory exceeded\n";
 static char islocked=0;

 if(!g_gotsound)
  return((void *) NULL);

 if(g_smmemory == (void *) NULL)
    if(!(g_smmemory = (void *) malloc(SMMEMORYSIZE)))
      fatalerror(errormsg1);

  if(amtreq < 0)
    {
	 retmempntr   = g_smmemory;
	 freemempntr  = g_smmemory;
	 g_smmleftover= SMMEMORYSIZE;
	 memset(g_smmemory,0,SMMEMORYSIZE);
	 if(!islocked)
	  {
       VMM_lock(g_smmemory, SMMEMORYSIZE);   // AIL function
	   islocked=1;
	  }
	 return((void *) NULL);
	}

  if(!amtreq)
	return((void *) NULL);

  if(((char *) freemempntr + amtreq) > ((char *) g_smmemory + SMMEMORYSIZE))
     fatalerror(errormsg2);

  g_smmleftover-=amtreq;

  retmempntr = freemempntr;
  (char*) freemempntr+=amtreq;

  return(retmempntr);
}

void FreeSceneMusicMemory(void)
 {
 if(g_smmemory != (void *) NULL)
  free(g_smmemory);
 g_smmemory=(void *) NULL;
 }
